/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | foam-extend: Open Source CFD
   \\    /   O peration     | Version:     4.1
    \\  /    A nd           | Web:         http://www.foam-extend.org
     \\/     M anipulation  | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
	This file is part of foam-extend.

	foam-extend is free software: you can redistribute it and/or modify it
	under the terms of the GNU General Public License as published by the
	Free Software Foundation, either version 3 of the License, or (at your
	option) any later version.

	foam-extend is distributed in the hope that it will be useful, but
	WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.

Class
	Foam::entry

Description
	A keyword and a list of tokens is an 'entry'.

	An entry can be read, written and printed, and the types and values of
	its tokens analysed.  An entry is a high-level building block for data
	description.  It is a front-end for the token parser. A list of entries
	can be used as a set of keyword syntax elements, for example.

SourceFiles
	entry.C
	entryIO.C

\*---------------------------------------------------------------------------*/

#ifndef entry_H
#define entry_H

#include "keyType.H"
#include "IDLList.H"
#include "fileName.H"
#include "autoPtr.H"
#include "infoSwitch.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{

class ITstream;
class dictionary;

// Forward declaration of friend functions and operators

class entry;
Ostream& operator<<(Ostream&, const entry&);


class entry
:
	public IDLList<entry>::link
{
	// Private data

		//- Keyword of entry
		keyType keyword_;


	// Private Member Functions

		//- Get the next valid keyword otherwise return false
		static bool getKeyword(keyType&, Istream&);


public:

	static debug::infoSwitch disableFunctionEntries;


	// Constructors

		//- Construct from keyword
		entry(const keyType&);

		//- Construct as copy
		entry(const entry&);

		//- Construct on freestore as copy with reference to the
		//  dictionary the copy belongs to
		virtual autoPtr<entry> clone
		(
			const dictionary& parentDict
		) const = 0;

		//- Construct on freestore as copy
		//  Note: the parent directory is set to dictionary::null
		virtual autoPtr<entry> clone() const;

		//- Construct from Istream and insert into dictionary
		static bool New(dictionary& parentDict, Istream&);

		//- Construct on freestore from Istream and return
		static autoPtr<entry> New(Istream& is);


	//- Destructor
	virtual ~entry()
	{}


	// Member functions

		//- Return keyword
		const keyType& keyword() const
		{
			return keyword_;
		}

		//- Return non-const access to keyword
		keyType& keyword()
		{
			return keyword_;
		}

		//- Return the dictionary name
		virtual const fileName& name() const = 0;

		//- Return the dictionary name
		virtual fileName& name() = 0;

		//- Return line number of first token in dictionary
		virtual label startLineNumber() const = 0;

		//- Return line number of last token in dictionary
		virtual label endLineNumber() const = 0;

		//- Return true if this entry is a stream
		virtual bool isStream() const
		{
			return false;
		}

		//- Return token stream if this entry is a primitive entry
		virtual ITstream& stream() const = 0;

		//- Return true if this entry is a dictionary
		virtual bool isDict() const
		{
			return false;
		}

		//- Return dictionary if this entry is a dictionary
		virtual const dictionary& dict() const = 0;

		//- Return non-const access to dictionary if this entry is a dictionary
		virtual dictionary& dict() = 0;

		//- Write
		virtual void write(Ostream&) const = 0;


	// Member operators

		void operator=(const entry&);

		bool operator==(const entry&) const;
		bool operator!=(const entry&) const;


	// Ostream operator

		friend Ostream& operator<<(Ostream&, const entry&);
};


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace Foam

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#endif

// ************************************************************************* //
